import axios from 'axios'
import config from './../config'
import { ElMessage } from 'element-plus'
import router from './../router'
import storage from '@/utils/storage.js'
import Nprogress from 'nprogress'

const Token_INVALID = 'Token认证失败,请重新登录'
const NetWork_ERROR = '网络请求异常，请稍后重试'

// 创建axios实例对象
const service = axios.create({
  baseURL: config.baseApi,
  timeout: 8000
})

// 请求拦截
// 添加请求拦截器
service.interceptors.request.use(
  (req) => {
    // 在发送请求之前做些什么
    const headers = req.headers
    const { token = '' } = storage.getItem('userInfo') || {}
    if (!headers.Authorization) headers.Authorization = 'Bearer ' + token
    // Nprogress.start()
    return req
  },
  function (error) {
    // 对请求错误做些什么
    return Promise.reject(error)
  }
)

// 添加响应拦截器
service.interceptors.response.use(
  (res) => {
    // 2xx 范围内的状态码都会触发该函数。
    // 对响应数据做点什么
    const { code, data, msg } = res.data
    // Nprogress.done()
    if (code === 200) {
      return data
    } else if (code === 500001) {
      //登录过期
      ElMessage.error(Token_INVALID)
      setTimeout(() => {
        router.push('/login')
      }, 1500)
      return Promise.reject(Token_INVALID)
    } else {
      ElMessage.error(msg || NetWork_ERROR)
      return Promise.reject(msg || NetWork_ERROR)
    }
  },
  function (error) {
    // 超出 2xx 范围的状态码都会触发该函数。
    // 对响应错误做点什么
    Nprogress.done()
    return Promise.reject(error)
  }
)

/* 
请求核心函数
@param {*} options 请求配置
*/
function request(options) {
  // 判断options的请求方式
  options.method = options.method || 'get'
  if (options.method.toLowerCase() === 'get') {
    options.params = options.data
  }
  let isMock = config.mock
  if (typeof options.mock != 'undefined') {
    isMock = options.mock
  }
  if (config.env === 'prod') {
    //生产模式指向baseApi
    service.defaults.baseURL = config.baseApi
  } else {
    service.defaults.baseURL = isMock ? config.mockApi : config.baseApi
  }
  return service(options)
}

;['get', 'post', 'put', 'delete', 'patch'].forEach((item) => {
  request[item] = (url, data, options) => {
    return request({
      url,
      data,
      method: item,
      ...options
    })
  }
})
export default request
